<template>
  <div class="streaming-demo">
    <div class="demo-header">
      <h2>流式数据处理演示</h2>
      <p>这个演示展示了如何处理包含思考过程的流式响应数据</p>
    </div>
    
    <div class="demo-controls">
      <button @click="simulateStreamingResponse" :disabled="isSimulating" class="demo-button">
        {{ isSimulating ? '模拟中...' : '开始模拟流式响应' }}
      </button>
      <button @click="clearDemo" class="demo-button secondary">清空演示</button>
      <label class="speed-control">
        <span>模拟速度:</span>
        <select v-model="simulationSpeed">
          <option value="50">快速 (50ms)</option>
          <option value="100">正常 (100ms)</option>
          <option value="200">慢速 (200ms)</option>
        </select>
      </label>
    </div>
    
    <div class="demo-content">
      <!-- 原始数据流 -->
      <div class="demo-section">
        <h3>原始数据流</h3>
        <div class="raw-stream" ref="rawStreamRef">
          <div v-for="(chunk, index) in rawChunks" :key="index" class="raw-chunk">
            <span class="chunk-index">[{{ index + 1 }}]</span>
            <span class="chunk-content">{{ JSON.stringify(chunk) }}</span>
          </div>
        </div>
      </div>
      
      <!-- 处理后的消息 -->
      <div class="demo-section">
        <h3>处理后的消息显示</h3>
        <div class="processed-message">
          <ChatMessage 
            v-if="demoMessage"
            :message="demoMessage"
            :enable-typewriter="false"
          />
          <div v-else class="empty-message">
            点击"开始模拟"按钮查看效果
          </div>
        </div>
      </div>
    </div>
    
    <!-- 统计信息 -->
    <div class="demo-stats" v-if="demoMessage">
      <div class="stat-grid">
        <div class="stat-item">
          <span class="stat-label">总字符数</span>
          <span class="stat-value">{{ demoMessage.content?.length || 0 }}</span>
        </div>
        <div class="stat-item">
          <span class="stat-label">思考字符数</span>
          <span class="stat-value">{{ demoMessage.thinkingContent?.length || 0 }}</span>
        </div>
        <div class="stat-item">
          <span class="stat-label">回答字符数</span>
          <span class="stat-value">{{ demoMessage.actualContent?.length || 0 }}</span>
        </div>
        <div class="stat-item">
          <span class="stat-label">数据块数量</span>
          <span class="stat-value">{{ rawChunks.length }}</span>
        </div>
      </div>
    </div>
  </div>
</template>

<script setup>
import { ref, nextTick } from 'vue'
import { v4 as uuidv4 } from 'uuid'
import ChatMessage from './ChatMessage.vue'

// 状态
const isSimulating = ref(false)
const simulationSpeed = ref(100)
const rawChunks = ref([])
const demoMessage = ref(null)
const rawStreamRef = ref(null)

// 模拟的流式数据（基于提供的示例）
const mockStreamData = [
  { type: "data", content: "<think>", metadata: { model: "qwen3:8b", threadId: "affde08e-c9d9-4fac-9094-31d1f052c987", temperature: 0.0, step: 1, node: "agent", provider: "openai" }},
  { type: "data", content: " ", metadata: { model: "qwen3:8b", threadId: "affde08e-c9d9-4fac-9094-31d1f052c987", temperature: 0.0, step: 1, node: "agent", provider: "openai" }},
  { type: "data", content: "好的", metadata: { model: "qwen3:8b", threadId: "affde08e-c9d9-4fac-9094-31d1f052c987", temperature: 0.0, step: 1, node: "agent", provider: "openai" }},
  { type: "data", content: "，", metadata: { model: "qwen3:8b", threadId: "affde08e-c9d9-4fac-9094-31d1f052c987", temperature: 0.0, step: 1, node: "agent", provider: "openai" }},
  { type: "data", content: "用户", metadata: { model: "qwen3:8b", threadId: "affde08e-c9d9-4fac-9094-31d1f052c987", temperature: 0.0, step: 1, node: "agent", provider: "openai" }},
  { type: "data", content: "打招呼", metadata: { model: "qwen3:8b", threadId: "affde08e-c9d9-4fac-9094-31d1f052c987", temperature: 0.0, step: 1, node: "agent", provider: "openai" }},
  { type: "data", content: "说", metadata: { model: "qwen3:8b", threadId: "affde08e-c9d9-4fac-9094-31d1f052c987", temperature: 0.0, step: 1, node: "agent", provider: "openai" }},
  { type: "data", content: "\"", metadata: { model: "qwen3:8b", threadId: "affde08e-c9d9-4fac-9094-31d1f052c987", temperature: 0.0, step: 1, node: "agent", provider: "openai" }},
  { type: "data", content: "你好", metadata: { model: "qwen3:8b", threadId: "affde08e-c9d9-4fac-9094-31d1f052c987", temperature: 0.0, step: 1, node: "agent", provider: "openai" }},
  { type: "data", content: "\"，", metadata: { model: "qwen3:8b", threadId: "affde08e-c9d9-4fac-9094-31d1f052c987", temperature: 0.0, step: 1, node: "agent", provider: "openai" }},
  { type: "data", content: "我", metadata: { model: "qwen3:8b", threadId: "affde08e-c9d9-4fac-9094-31d1f052c987", temperature: 0.0, step: 1, node: "agent", provider: "openai" }},
  { type: "data", content: "需要", metadata: { model: "qwen3:8b", threadId: "affde08e-c9d9-4fac-9094-31d1f052c987", temperature: 0.0, step: 1, node: "agent", provider: "openai" }},
  { type: "data", content: "回应", metadata: { model: "qwen3:8b", threadId: "affde08e-c9d9-4fac-9094-31d1f052c987", temperature: 0.0, step: 1, node: "agent", provider: "openai" }},
  { type: "data", content: "。", metadata: { model: "qwen3:8b", threadId: "affde08e-c9d9-4fac-9094-31d1f052c987", temperature: 0.0, step: 1, node: "agent", provider: "openai" }},
  { type: "data", content: "</think>", metadata: { model: "qwen3:8b", threadId: "affde08e-c9d9-4fac-9094-31d1f052c987", temperature: 0.0, step: 1, node: "agent", provider: "openai" }},
  { type: "data", content: "  ", metadata: { model: "qwen3:8b", threadId: "affde08e-c9d9-4fac-9094-31d1f052c987", temperature: 0.0, step: 1, node: "agent", provider: "openai" }},
  { type: "data", content: "你好", metadata: { model: "qwen3:8b", threadId: "affde08e-c9d9-4fac-9094-31d1f052c987", temperature: 0.0, step: 1, node: "agent", provider: "openai" }},
  { type: "data", content: "！", metadata: { model: "qwen3:8b", threadId: "affde08e-c9d9-4fac-9094-31d1f052c987", temperature: 0.0, step: 1, node: "agent", provider: "openai" }},
  { type: "data", content: "有什么", metadata: { model: "qwen3:8b", threadId: "affde08e-c9d9-4fac-9094-31d1f052c987", temperature: 0.0, step: 1, node: "agent", provider: "openai" }},
  { type: "data", content: "可以", metadata: { model: "qwen3:8b", threadId: "affde08e-c9d9-4fac-9094-31d1f052c987", temperature: 0.0, step: 1, node: "agent", provider: "openai" }},
  { type: "data", content: "帮", metadata: { model: "qwen3:8b", threadId: "affde08e-c9d9-4fac-9094-31d1f052c987", temperature: 0.0, step: 1, node: "agent", provider: "openai" }},
  { type: "data", content: "你的", metadata: { model: "qwen3:8b", threadId: "affde08e-c9d9-4fac-9094-31d1f052c987", temperature: 0.0, step: 1, node: "agent", provider: "openai" }},
  { type: "data", content: "吗", metadata: { model: "qwen3:8b", threadId: "affde08e-c9d9-4fac-9094-31d1f052c987", temperature: 0.0, step: 1, node: "agent", provider: "openai" }},
  { type: "data", content: "？", metadata: { model: "qwen3:8b", threadId: "affde08e-c9d9-4fac-9094-31d1f052c987", temperature: 0.0, step: 1, node: "agent", provider: "openai" }}
]

// 模拟流式响应
const simulateStreamingResponse = async () => {
  if (isSimulating.value) return
  
  isSimulating.value = true
  rawChunks.value = []
  
  // 初始化演示消息
  demoMessage.value = {
    id: uuidv4(),
    content: '',
    role: 'assistant',
    timestamp: new Date().toISOString(),
    metadata: null,
    thinkingContent: '',
    actualContent: '',
    isStreaming: true
  }
  
  let accumulatedContent = ''
  let isInThinkingMode = false
  let thinkingContent = ''
  let actualContent = ''
  
  try {
    for (let i = 0; i < mockStreamData.length; i++) {
      const chunk = mockStreamData[i]
      
      // 添加到原始数据流
      rawChunks.value.push(chunk)
      
      // 处理数据块
      if (chunk.type === 'data' && chunk.content) {
        const chunkContent = chunk.content
        accumulatedContent += chunkContent
        
        // 检测思考标签
        if (chunkContent.includes('<think>')) {
          isInThinkingMode = true
        }
        
        if (isInThinkingMode) {
          thinkingContent += chunkContent
          
          // 检测思考结束
          if (chunkContent.includes('</think>')) {
            isInThinkingMode = false
            // 提取纯思考内容（去除标签）
            const thinkMatch = thinkingContent.match(/<think>([\s\S]*?)<\/think>/i)
            if (thinkMatch) {
              thinkingContent = thinkMatch[1].trim()
            }
          }
        } else {
          // 不在思考模式，累积实际回答内容
          actualContent += chunkContent
        }
        
        // 更新演示消息
        demoMessage.value = {
          ...demoMessage.value,
          content: accumulatedContent,
          thinkingContent: isInThinkingMode ? thinkingContent : thinkingContent.replace(/<\/?think>/gi, '').trim(),
          actualContent: actualContent.replace(/<\/?think>/gi, '').trim(),
          metadata: chunk.metadata,
          isStreaming: i < mockStreamData.length - 1
        }
      }
      
      // 滚动到底部
      await nextTick()
      scrollToBottom()
      
      // 等待指定时间
      await new Promise(resolve => setTimeout(resolve, parseInt(simulationSpeed.value)))
    }
    
    // 完成流式响应
    demoMessage.value.isStreaming = false
    
  } finally {
    isSimulating.value = false
  }
}

// 清空演示
const clearDemo = () => {
  rawChunks.value = []
  demoMessage.value = null
}

// 滚动到底部
const scrollToBottom = () => {
  if (rawStreamRef.value) {
    rawStreamRef.value.scrollTop = rawStreamRef.value.scrollHeight
  }
}
</script>

<style scoped>
.streaming-demo {
  max-width: 1200px;
  margin: 0 auto;
  padding: 20px;
  font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
}

.demo-header {
  text-align: center;
  margin-bottom: 30px;
}

.demo-header h2 {
  color: #333;
  margin-bottom: 10px;
}

.demo-header p {
  color: #666;
  font-size: 14px;
}

.demo-controls {
  display: flex;
  gap: 16px;
  align-items: center;
  justify-content: center;
  margin-bottom: 30px;
  flex-wrap: wrap;
}

.demo-button {
  padding: 10px 20px;
  border: none;
  border-radius: 6px;
  cursor: pointer;
  font-weight: 500;
  transition: all 0.2s;
}

.demo-button:not(.secondary) {
  background: #007bff;
  color: white;
}

.demo-button:not(.secondary):hover:not(:disabled) {
  background: #0056b3;
}

.demo-button.secondary {
  background: #6c757d;
  color: white;
}

.demo-button.secondary:hover {
  background: #545b62;
}

.demo-button:disabled {
  opacity: 0.6;
  cursor: not-allowed;
}

.speed-control {
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 14px;
  color: #666;
}

.speed-control select {
  padding: 4px 8px;
  border: 1px solid #ddd;
  border-radius: 4px;
  background: white;
}

.demo-content {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 20px;
  margin-bottom: 30px;
}

.demo-section {
  background: white;
  border: 1px solid #e9ecef;
  border-radius: 8px;
  overflow: hidden;
}

.demo-section h3 {
  background: #f8f9fa;
  margin: 0;
  padding: 12px 16px;
  font-size: 16px;
  font-weight: 600;
  color: #333;
  border-bottom: 1px solid #e9ecef;
}

.raw-stream {
  height: 400px;
  overflow-y: auto;
  padding: 16px;
  font-family: monospace;
  font-size: 12px;
  background: #f8f9fa;
}

.raw-stream::-webkit-scrollbar {
  width: 6px;
}

.raw-stream::-webkit-scrollbar-track {
  background: #f1f1f1;
}

.raw-stream::-webkit-scrollbar-thumb {
  background: #c1c1c1;
  border-radius: 3px;
}

.raw-chunk {
  margin-bottom: 8px;
  padding: 6px;
  background: white;
  border-radius: 4px;
  border-left: 3px solid #007bff;
  word-break: break-all;
}

.chunk-index {
  color: #007bff;
  font-weight: bold;
  margin-right: 8px;
}

.chunk-content {
  color: #333;
}

.processed-message {
  min-height: 400px;
  padding: 16px;
  background: white;
}

.empty-message {
  display: flex;
  align-items: center;
  justify-content: center;
  height: 100%;
  color: #6c757d;
  font-style: italic;
}

.demo-stats {
  background: white;
  border: 1px solid #e9ecef;
  border-radius: 8px;
  padding: 20px;
}

.stat-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
  gap: 16px;
}

.stat-item {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 12px;
  background: #f8f9fa;
  border-radius: 6px;
}

.stat-label {
  color: #666;
  font-weight: 500;
}

.stat-value {
  color: #007bff;
  font-weight: bold;
  font-size: 18px;
}

/* 响应式设计 */
@media (max-width: 768px) {
  .streaming-demo {
    padding: 16px;
  }
  
  .demo-controls {
    flex-direction: column;
    align-items: stretch;
  }
  
  .demo-content {
    grid-template-columns: 1fr;
    gap: 16px;
  }
  
  .raw-stream {
    height: 300px;
    font-size: 11px;
  }
  
  .processed-message {
    min-height: 300px;
  }
  
  .stat-grid {
    grid-template-columns: 1fr;
  }
}
</style>